/*
 *  Copyright (C) 2009 Dominik Psenner, Christoph Caks
 * 
 *   This file is part of project-blog.
 *
 *  project-blog is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  project-blog is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with project-blog.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
package com.blog.cron;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNProperties;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;

/**
 * 
 * @author dominik
 * 
 */
public class SVNSynchServlet extends HttpServlet {
	private static final long serialVersionUID = 5256819219263852309L;
	private static final Logger log = Logger.getLogger(SVNSynchServlet.class);
	
	@Override
	protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
		log.trace("doGet() - BEGIN");
		synch();
		log.trace("doGet() - END");
	}
	
	/*
	 * Initializes the library to work with a repository via different protocols.
	 */
	private static void setupLibrary() {
		/*
		 * For using over http:// and https://
		 */
		DAVRepositoryFactory.setup();
		/*
		 * For using over svn:// and svn+xxx://
		 */
		SVNRepositoryFactoryImpl.setup();
		
		/*
		 * For using over file:///
		 */
		FSRepositoryFactory.setup();
	}
	
	/**
	 * 
	 */
	public void synch() {
		setupLibrary();
		// create svn urls to connect to
		final List<SVNURL> svnurls = new LinkedList<SVNURL>();
		try {
			svnurls.add(SVNURL.create("http", null, "project-blog.googlecode.com", 80, "/svn/branches/blogs/", false));
		}
		catch (final SVNException e) {
			// failed
			log.error("Could not create SVN url to project-blog.googlecode.com", e);
		}
		for (final SVNURL url : svnurls) {
			try {
				final SVNRepository repository = SVNRepositoryFactory.create(url);
				final long revision = repository.getDatedRevision(new Date());
				final String path = "";
				final SVNNodeKind nodeKind = repository.checkPath(path, -1);
				
				if (nodeKind.equals(SVNNodeKind.DIR)) {
					// fine, is directory, fetch childs
					final List<SVNDirEntry> entries = new LinkedList<SVNDirEntry>();
					final SVNDirEntry entry = repository.getDir(path, revision, true, entries);
					log.debug("Entry containing the blogs: " + getURLString(url, entry));
					log.debug("Blogs found: ");
					for (final SVNDirEntry e : entries) {
						if (e instanceof SVNDirEntry) {
							if (e.getKind().equals(SVNNodeKind.FILE)) {
								log.debug("ENTRY Rev" + e.getRevision() + " - " + e.getURL());
								final OutputStream os = System.out;
								repository.getFile(e.getRelativePath(), revision, new SVNProperties(), os);
							}
							else if (e.getKind().equals(SVNNodeKind.DIR)) {
								log.debug("DIR Rev" + e.getRevision() + " - " + e.getURL());
							}
							else {
								log.warn("Unknown SVN kind: " + e.getKind());
							}
						}
						else {
							log.warn("Unknown entry type: " + e);
						}
					}
				}
			}
			catch (final SVNException e) {
				log.error("Could not get SVN information due to exception.", e);
			}
		}
	}
	
	public String getURLString(final SVNURL url, final SVNDirEntry entry) {
		return url.toString() + "/" + entry.getRelativePath();
	}
}
